/*
 * <copyright>
 *
 * Copyright (c) 2007 Dieter Moroff and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Dieter Moroff - Initial API and implementation
 *
 * </copyright>
 */

package org.openarchitectureware.adapter.rsdp.plugin;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.osgi.framework.Bundle;

/**
 * URIConverter to load UML2 model stored by IBM RSM/RSA. Uses pathmap-entries
 * registered at the extenstionpoint <pre>org.eclipse.gmf.runtime.emf.core.Pathmaps</pre> 
 * 
 * @author Dieter Moroff (10.01.2007) (Last change $Author: pschoenb $ $Date: 2008/06/10 12:18:53 $)
 */
public class PathMapURIConverter extends URIConverterImpl {
   private final static String pathmapExtensionPointId = "org.eclipse.gmf.runtime.emf.core.Pathmaps";
   private final URIConverter converter;
   private Map<String, URI> pathMap;
   
   public PathMapURIConverter(URIConverter converter) {
      super();
      this.converter = converter;
   }

   /** 
    * Load the pathmap entrys from extension point
    */
   private void init() {
      if ( pathMap == null ) {
         pathMap = new HashMap<String, URI>();
         
         IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
         IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(pathmapExtensionPointId);
         if ( extensionPoint != null ) {
            IExtension extensions[] = extensionPoint.getExtensions();
            
            for (int i = 0; i < extensions.length; i++) {
               IExtension extension = extensions[i];
               IConfigurationElement elements[] = extension.getConfigurationElements();

               for (int j = 0; j < elements.length; j++) {
                  IConfigurationElement element = elements[j];
                  String profilePath  = element.getAttribute("path");
                  String pluginId = element.getAttribute("plugin");
                  String alias = element.getAttribute("name");
                  
                  if ( pluginId == null ) {
                     pluginId = extension.getNamespaceIdentifier();
                  }
                  
                  Bundle bundle = Platform.getBundle(pluginId);
                  
                  if ( bundle != null ) {
                     URL location = bundle.getEntry(profilePath);
                     URI mappedURL = URI.createURI(location.toExternalForm());
   
                     pathMap.put(alias, mappedURL);
                  }
               }
            }
         }
      }
   }
   
   /* (non-Javadoc)
    * @see org.eclipse.emf.ecore.resource.URIConverter#normalize(org.eclipse.emf.common.util.URI)
    */
   public URI normalize(URI uri) {
      init();
      URI normalizedURI = null;
      
      if ( uri.scheme() != null && uri.scheme().equals("pathmap")) {
         String host = uri.host();
         URI mappedURI = pathMap.get(host);
         
         if ( mappedURI != null ) {
            String path = uri.path();
            normalizedURI = URI.createURI(mappedURI.toString().concat(path));
         }
         else {
            normalizedURI = converter.normalize(uri);
         }
      }
      else {
         normalizedURI = converter.normalize(uri); 
      }
      
      return normalizedURI; 
   }


   /* (non-Javadoc)
    * @see org.eclipse.emf.ecore.resource.URIConverter#getURIMap()
    */
   public Map<URI,URI> getURIMap() {
      return converter.getURIMap();
   }

   /* (non-Javadoc)
    * @see org.eclipse.emf.ecore.resource.URIConverter#createInputStream(org.eclipse.emf.common.util.URI)
    */
   public InputStream createInputStream(URI uri) throws IOException {
      InputStream inputStream = null;
      
      if ( uri.scheme() != null && uri.scheme().equals("pathmap") ) {
         String host = uri.host();
         URI mappedURI = pathMap.get(host);
         
         if ( mappedURI != null ) {
            String path = uri.path();
            URI normalizedURI = URI.createURI(mappedURI.toString().concat(path));

            inputStream = createInputStream(normalizedURI);
         }
         else {
            inputStream = converter.createInputStream(uri);
         }
      }
      else {
         inputStream = converter.createInputStream(uri);
      }

      return inputStream;
   }

   /* (non-Javadoc)
    * @see org.eclipse.emf.ecore.resource.URIConverter#createOutputStream(org.eclipse.emf.common.util.URI)
    */
   public OutputStream createOutputStream(URI uri) throws IOException {
      return converter.createOutputStream(uri);
   }

}
